/**
 * 抽象类PropertySource，用于表示一个属性源
 * 它提供了一种机制来访问源中的属性，但不指定如何存储或管理这些属性
 *
 * @param <T> 源的类型，它可以是任何对象，如Map、数据库连接等
 */
package com.test.source;

public abstract class PropertySource<T>{

    // 属性源的名称，用于标识属性源
    private final String name;

    // 属性源对象，具体类型由泛型T指定
    protected final T source;

    /**
     * 构造方法，用于创建一个具有指定名称和源的属性源实例
     *
     * @param name 属性源的名称
     * @param source 属性源对象
     */
    public PropertySource(String name, T source) {
        this.name = name;
        this.source = source;
    }

    /**
     * 获取属性源的名称
     *
     * @return 属性源的名称
     */
    public String getName() {
        return name;
    }

    /**
     * 获取属性源对象
     *
     * @return 属性源对象
     */
    public T getSource() {
        return source;
    }

    /**
     * 判断属性源是否包含指定名称的属性
     *
     * @param name 属性名称
     * @return 如果包含则返回true，否则返回false
     */
    public boolean containsProperty(String name) {
        return getProperty(name) != null;
    }

    /**
     * 获取指定名称的属性
     * 此方法需要由子类具体实现，因为属性的实际获取方式取决于属性源的类型
     *
     * @param name 属性名称
     * @return 属性值，如果不存在则返回null
     */
    public abstract Object getProperty(String name);

    /**
     * 重写equals方法，用于判断两个属性源是否相等
     * 两个属性源相等的条件是它们的名称相等
     *
     * @param other 另一个对象
     * @return 如果两个属性源相等则返回true，否则返回false
     */
    public boolean equals(Object other) {
        if (this == other){
            return true;
        }
        if (!(other instanceof PropertySource)){
            return false;
        }
        PropertySource<?> otherPs = (PropertySource<?>) other;
        return this.name.equals(otherPs.name);
    }

    /**
     * 重写hashCode方法，用于生成属性源的哈希码
     * 基于属性源的名称生成哈希码
     *
     * @return 属性源的哈希码
     */
    public int hashCode() {
        return this.name.hashCode();
    }

    /**
     * 重写toString方法，用于生成属性源的字符串表示
     *
     * @return 属性源的字符串表示
     */
    public String toString() {
        return "PropertySource '" + this.name + "': " + this.source;
    }
}
